import os
from datetime import timedelta
from minio import Minio
from minio.error import S3Error
import logging

# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class minio_client:
    def __init__(self, endpoint, access_key, secret_key, secure=False):
        # 初始化 MinIO 客户端
        self.client = Minio(
            endpoint,
            access_key=access_key,
            secret_key=secret_key,
            secure=secure
        )
        logging.info(f"MinIO client initialized with endpoint: {endpoint}")

    def create_bucket(self, bucket_name):
        """创建一个新的桶，如果桶已存在则打印提示信息"""
        try:
            if not self.client.bucket_exists(bucket_name):
                self.client.make_bucket(bucket_name)
                logging.info(f"Bucket {bucket_name} created successfully.")
            else:
                logging.info(f"Bucket {bucket_name} already exists.")
        except S3Error as err:
            logging.error(f"Failed to create bucket {bucket_name}: {err}")
            raise

    def put_object_by_path(self, bucket_name, file_path, object_name):
        """上传文件到指定的桶中"""
        try:
            file_size = os.path.getsize(file_path)
            with open(file_path, 'rb') as file_data:
                self.client.put_object(bucket_name, object_name, file_data, length=file_size)
            logging.info(f"File {object_name} uploaded successfully.")
        except FileNotFoundError:
            logging.error(f"File {file_path} not found.")
            raise
        except PermissionError:
            logging.error(f"Permission denied when accessing file {file_path}.")
            raise
        except S3Error as err:
            logging.error(f"Error uploading file {object_name}: {err}")
            raise

    def fput_object_by_path(self, bucket_name, file_path, object_name, content_type='application/octet-stream'):
        """使用 fput_object 方法上传文件"""
        try:
            self.client.fput_object(bucket_name, object_name, file_path, content_type=content_type)
            logging.info(f"File {object_name} uploaded with fput_object.")
        except FileNotFoundError:
            logging.error(f"File {file_path} not found.")
            raise
        except PermissionError:
            logging.error(f"Permission denied when accessing file {file_path}.")
            raise
        except S3Error as err:
            logging.error(f"Error uploading file {object_name}: {err}")
            raise

    def download_file(self, bucket_name, object_name, path):
        """从指定的桶中下载文件"""
        try:
            data = self.client.get_object(bucket_name, object_name)
            with open(path, "wb") as fp:
                for d in data.stream(1024 * 1024):
                    fp.write(d)
            logging.info(f"File {object_name} downloaded successfully.")
        except S3Error as err:
            logging.error(f"Error downloading file {object_name}: {err}")
            raise

    def delete_file(self, bucket_name, object_name):
        """从指定的桶中删除文件"""
        try:
            self.client.remove_object(bucket_name, object_name)
            logging.info(f"File {object_name} deleted successfully.")
        except S3Error as err:
            logging.error(f"Error deleting file {object_name}: {err}")
            raise

    def get_presigned_url(self, bucket_name, object_name, expires=timedelta(days=1)):
        """生成预签名的 URL，用于临时访问对象"""
        try:
            presigned_url = self.client.presigned_get_object(bucket_name, object_name, expires=expires)
            logging.info(f"Presigned URL for {object_name}: {presigned_url}")
            return presigned_url
        except S3Error as err:
            logging.error(f"Failed to generate presigned URL for {object_name}: {err}")
            return None

# 示例用法
if __name__ == "__main__":
    # MinIO 服务地址、端口、访问密钥和秘密密钥
    endpoint = "127.0.0.1:9000"
    access_key = "5BUOEY89smdaZC0JJ8Bb"
    secret_key = "WUiySvIGviO9IJrds8HWEAFObh5tw8oNZxX2FCWk"

    # 创建 MinIO 客户端实例
    minio_client = minio_client(endpoint, access_key, secret_key)

    # 创建桶
    bucket_name = "student-sys"
    # minio_client.create_bucket(bucket_name)

    # # 上传文件
    # file_path = "/path/to/your/file.txt"
    # object_name = "file.txt"
    # minio_client.put_object_by_path(bucket_name, file_path, object_name)
    #
    # 生成预签名 URL
    object_name = "ibai-tools/user-avatars/19f4cea6d8a34ae7b4ebf3c529599d4e.1.版本分支.png"
    presigned_url = minio_client.get_presigned_url(bucket_name, object_name)
    print(f"Presigned URL: {presigned_url}")
    #
    # # 下载文件
    # download_path = "/path/to/downloaded/file.txt"
    # minio_client.download_file(bucket_name, object_name, download_path)
    #
    # # 删除文件
    # minio_client.delete_file(bucket_name, object_name)